﻿/***************************************************************
 * 开发人员：网魂小兵@http://www.mozlite.com
 * 
 * 辅助方法类。
 * 
 * 最后修改：2011-10-19
 * ************************************************************/
namespace Mozlite
{
    #region usings
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.IO;
    using System.Reflection;
    using System.Web.Hosting;
    using System.Text.RegularExpressions;
    using System.Security.Permissions;
    using System.Web;
    using System.Security;
    using System.Collections.Specialized;
    using System.Xml.Serialization;
    using System.Globalization;
    using System.Runtime.Serialization;
    using System.Runtime.Serialization.Formatters.Soap;
    using System.Xml;
    using System.Runtime.Serialization.Formatters.Binary;
    using Mozlite.Cryptography;
    using System.Drawing.Imaging;
    using System.Drawing;
    using System.Drawing.Drawing2D;
    using System.Web.UI.WebControls;
    using System.Net;
    using System.Diagnostics;
    using System.Runtime.InteropServices;
    #endregion

    /// <summary>
    /// 通用辅助方法。
    /// </summary>
    public class CommonHelper
    {
        #region initializers
        /// <summary>
        /// 初始化类<see cref="T:Mozlite.CommonHelper"/>。
        /// </summary>
        protected CommonHelper() { }

        static CommonHelper() {
            SecurityPermission permission = new SecurityPermission(SecurityPermissionFlag.SerializationFormatter);
            try
            {
                permission.Demand();
                CanBinarySerialize = true;
            }
            catch (SecurityException)
            {
                CanBinarySerialize = false;
            }
            try
            {
                ApplicationPath = HttpRuntime.AppDomainAppPath;
                ApplicationUrl = HttpRuntime.AppDomainAppVirtualPath;
            }
            catch
            {
                ApplicationUrl = "/";
            }
        }
        /// <summary>
        /// 是否能二进制序列化。
        /// </summary>
        public static readonly bool CanBinarySerialize;
        #endregion

        #region path methods
        /// <summary>
        /// 获取应用程序物理目录。
        /// </summary>
        public static string ApplicationPath
        {
            get;
            private set;
        }

        /// <summary>
        /// 获取应用程序虚拟目录。
        /// </summary>
        public static string ApplicationUrl
        {
            get;
            private set;
        }

        private static Regex pathSepFilter = new Regex("(\\\\|/)+", RegexOptions.Compiled);
        private static Regex proFilter = new Regex("([a-z]+:)/+", RegexOptions.Compiled);

        /// <summary>
        /// 连接两个路径，包含物理路径，如果path为空字符串返回不带“/”或“\”的路径。
        /// </summary>
        /// <param name="root">前段路径。</param>
        /// <param name="path">末端路径。</param>
        /// <param name="isPhysicsPath">是否为物理路径。</param>
        /// <returns>连接两个URL路径，如果path为空字符串返回不带“/”或“\”的路径。</returns>
        public static string Combine(string root, string path, bool isPhysicsPath = false)
        {
            if (string.IsNullOrEmpty(path))
                return root;
            path = root + "\\" + path;
            if (isPhysicsPath)
            {
                path = pathSepFilter.Replace(path, "\\");
            }
            else
            {
                path = proFilter.Replace(pathSepFilter.Replace(path, "/"), "$1//");
            }
            return path.TrimEnd('\\', '/');
        }

        /// <summary>
        /// 获取物理路径。
        /// </summary>
        /// <param name="virtualPath">虚拟路径。</param>
        /// <returns>返回物理路径。</returns>
        public static string MapPath(string virtualPath)
        {
            if (string.IsNullOrEmpty(virtualPath))
                return ApplicationPath;
            virtualPath = virtualPath.Trim();
            string path = HostingEnvironment.MapPath(virtualPath);
            if (path != null)
            {
                return path;
            }
            if (!virtualPath.StartsWith("~/"))
                throw new Exception("The path not starts with ~, can not map!");
            virtualPath = virtualPath.Substring(2);
            return Combine(ApplicationPath, virtualPath, true);
        }

        /// <summary>
        /// 如果文件夹不存在则创建文件夹。
        /// </summary>
        /// <param name="path">文件夹的物理路径。</param>
        public static void CreateDirectory(string path)
        {
            if (!string.IsNullOrEmpty(path) && !Directory.Exists(path))
                Directory.CreateDirectory(path);
        }

        /// <summary>
        /// 设置Url的查询字符串。
        /// </summary>
        /// <param name="url">Url地址。</param>
        /// <param name="key">查询键。</param>
        /// <param name="value">值。</param>
        /// <returns>返回更新后的URL地址。</returns>
        public static string SetQueryString(string url, string key, object value)
        {
            int index = url.IndexOf('?');
            if (index == -1)
                return url + "?" + key + "=" + value;
            string host = url.Substring(0, index + 1);
            url = url.Substring(index + 1) + "&" + key + "=" + value;
            return host + FromString(url).Join("&");
        }

        /// <summary>
        /// 获取临时文件夹文件的物理路径。
        /// </summary>
        /// <returns>返回新文件的物理路径。</returns>
        public static string GetNewTempPath() {
            string path = GetPath("temp");
            CreateDirectory(path);
            return Combine(path, Guid.NewGuid().ToString(), true);
        }

        /// <summary>
        /// 获取用户文件物理路径。
        /// </summary>
        /// <param name="args">路径参数。</param>
        /// <returns>返回用户文件物理路径。</returns>
        public static string GetUserFilePath(params object[] args) {
            string file = null;
            if (args != null)
                file = args.Join("/");
            file = GetPath("userfiles", file);
            CreateDirectory(Path.GetDirectoryName(file));
            return file;
        }

        /// <summary>
        /// 获取用户文件URL路径。
        /// </summary>
        /// <param name="args">路径参数。</param>
        /// <returns>返回用户文件URL路径。</returns>
        public static string GetUserFileUrl(params object[] args)
        {
            return GetUrl("userfiles", args);
        }

        /// <summary>
        /// 获取物理路径。
        /// </summary>
        /// <param name="args">路径参数。</param>
        /// <returns>返回物理路径。</returns>
        public static string GetPath(params object[] args)
        {
            string file = ApplicationPath;
            if (args != null)
            {
                string path = args.Join("/");
                if (path.StartsWith("~"))
                    path = path.Substring(1);
                file = Combine(file, path);
            }
            return file;
        }

        /// <summary>
        /// 获取URL地址。
        /// </summary>
        /// <param name="args">路径参数。</param>
        /// <returns>返回URL地址。</returns>
        public static string GetUrl(params object[] args)
        {
            if(args == null)
                return ApplicationUrl;
            string path = args.Join("/");
            if(path.StartsWith("~"))
                path = path.Substring(1);
            return Combine(ApplicationUrl, path);
        }

        /// <summary>
        /// 获取URL地址。
        /// </summary>
        /// <param name="args">路径参数。</param>
        /// <returns>返回URL地址。</returns>
        public static string GetUtil(params object[] args)
        {
            string file = ApplicationUrl + "_utilities";
            if (args != null)
            {
                string path = args.Join("/");
                if (path.StartsWith("~"))
                    path = path.Substring(1);
                file = Combine(file, path);
            }
            return file;
        }

        /// <summary>
        /// 获取文件扩展名，不包含“.”。
        /// </summary>
        /// <param name="fileName">文件名。</param>
        /// <returns>返回扩展名。</returns>
        public static string GetExtension(string fileName) {
            string key = Path.GetExtension(fileName);
            if (fileName.IndexOf('.') <= 0)
                key = fileName;
            key = key.Trim(new char[] { ' ', '.' });
            return key;
        }
        #endregion

        #region serializer
        /// <summary>
        /// 将文件序列化为类型。
        /// </summary>
        /// <typeparam name="T">要序列化类型。</typeparam>
        /// <param name="path">路径。</param>
        /// <returns>返回文件序列化后的类型对象。</returns>
        public static T ConvertFileToObject<T>(string path)
        {
            T obj = default(T);
            if ((path != null) && (path.Length > 0))
            {
                using (FileStream stream = new FileStream(path, FileMode.Open, FileAccess.Read))
                {
                    obj = (T)new XmlSerializer(typeof(T)).Deserialize(stream);
                    stream.Close();
                }
            }
            return obj;
        }
        /// <summary>
        /// 将SOAP的XML文本字符串序列化为类型。
        /// </summary>
        /// <typeparam name="T">要序列化的类型。</typeparam>
        /// <param name="xml">XML字符串。</param>
        /// <returns>返回序列化后的类型对象。</returns>
        public static T ConvertSOAPToObject<T>(string xml)
        {
            MemoryStream serializationStream = null;
            T obj;
            try
            {
                IFormatter formatter = new SoapFormatter();
                serializationStream = new MemoryStream(Encoding.Default.GetBytes(xml));
                obj = (T)formatter.Deserialize(serializationStream);
            }
            finally
            {
                if (serializationStream != null)
                {
                    serializationStream.Close();
                }
            }
            return obj;
        }
        /// <summary>
        /// 将对象序列化为二进制数组。
        /// </summary>
        /// <param name="objectToConvert">将要序列化的对象实例。</param>
        /// <returns>返回二进制数组。</returns>
        public static byte[] ConvertToBytes(object objectToConvert)
        {
            byte[] buffer = null;
            if (CanBinarySerialize)
            {
                BinaryFormatter formatter = new BinaryFormatter();
                using (MemoryStream stream = new MemoryStream())
                {
                    formatter.Serialize(stream, objectToConvert);
                    stream.Position = 0L;
                    buffer = new byte[stream.Length];
                    stream.Read(buffer, 0, buffer.Length);
                    stream.Close();
                }
            }
            return buffer;
        }
        /// <summary>
        /// 将字符串序列化为二进制数组。
        /// </summary>
        /// <param name="s">用于序列化的字符串。</param>
        /// <returns>返回二进制数组。</returns>
        public static byte[] ConvertToBytes(string s)
        {
            return Convert.FromBase64String(s);
        }
        /// <summary>
        /// 将二进制数组反序列化为对象。
        /// </summary>
        /// <typeparam name="T">当前类型。</typeparam>
        /// <param name="buffer">二进制数组。</param>
        /// <returns>返回当前类型实例对象。</returns>
        public static T ConvertToObject<T>(byte[] buffer)
        {
            T obj = default(T);
            if (CanBinarySerialize && buffer != null && buffer.Length > 0)
            {
                BinaryFormatter formatter = new BinaryFormatter();
                using (MemoryStream stream = new MemoryStream())
                {
                    stream.Write(buffer, 0, buffer.Length);
                    stream.Position = 0L;
                    if (buffer.Length > 4)
                    {
                        obj = (T)formatter.Deserialize(stream);
                    }
                    stream.Close();
                }
            }
            return obj;
        }
        /// <summary>
        /// 将XML字符串反序列化为对象。
        /// </summary>
        /// <typeparam name="T">当前类型。</typeparam>
        /// <param name="xml">XML字符串。</param>
        /// <returns>返回当前类型实例对象。</returns>
        public static T ConvertToObject<T>(string xml)
        {
            T obj = default(T);
            if (!string.IsNullOrEmpty(xml))
            {
                using (StringReader reader = new StringReader(xml))
                {
                    XmlSerializer serializer = new XmlSerializer(typeof(T));
                    try
                    {
                        obj = (T)serializer.Deserialize(reader);
                    }
                    catch (InvalidOperationException)
                    {
                    }
                    reader.Close();
                }
            }
            return obj;
        }
        /// <summary>
        /// 将XML字符串反序列化为对象。
        /// </summary>
        /// <param name="xml">XML字符串。</param>
        /// <typeparam name="type">当前类型。</typeparam>
        /// <returns>返回当前类型实例对象。</returns>
        public static object ConvertToObject(string xml, Type type)
        {
            object obj = null;
            if (!string.IsNullOrEmpty(xml))
            {
                using (StringReader reader = new StringReader(xml))
                {
                    XmlSerializer serializer = new XmlSerializer(type);
                    try
                    {
                        obj = serializer.Deserialize(reader);
                    }
                    catch (InvalidOperationException)
                    {
                    }
                    reader.Close();
                }
            }
            return obj;
        }
        /// <summary>
        /// 将XML节点反序列化为对象。
        /// </summary>
        /// <typeparam name="T">当前类型。</typeparam>
        /// <param name="node">XML节点。</param>
        /// <returns>返回当前类型实例对象。</returns>
        public static T ConvertToObject<T>(XmlNode node)
        {
            T obj = default(T);
            if (node != null)
            {
                using (StringReader reader = new StringReader(node.OuterXml))
                {
                    XmlSerializer serializer = new XmlSerializer(typeof(T));
                    try
                    {
                        obj = (T)serializer.Deserialize(reader);
                    }
                    catch (InvalidOperationException)
                    {
                    }
                    reader.Close();
                }
            }
            return obj;
        }
        /// <summary>
        /// 将对象序列化为SOAP字符串。
        /// </summary>
        /// <param name="s">用于序列化的对象实例。</param>
        /// <returns>返回SOAP字符串。</returns>
        public static string ConvertToSOAPString(object obj)
        {
            MemoryStream serializationStream = null;
            string str;
            try
            {
                serializationStream = new MemoryStream();
                IFormatter formatter = new SoapFormatter();
                formatter.Serialize(serializationStream, obj);
                int length = (int)serializationStream.Length;
                byte[] buffer = new byte[length];
                serializationStream.Seek(0L, SeekOrigin.Begin);
                serializationStream.Read(buffer, 0, length);
                UTF8Encoding encoding = new UTF8Encoding();
                str = encoding.GetString(buffer).Trim();
            }
            finally
            {
                if (serializationStream != null)
                {
                    serializationStream.Close();
                }
            }
            return str;
        }
        /// <summary>
        /// 将对象序列化为字符串。
        /// </summary>
        /// <param name="objectToConvert">要序列化的对象。</param>
        /// <returns>返回序列化后的字符串。</returns>
        public static string ConvertObjectToString(object objectToConvert)
        {
            string str = null;
            if (objectToConvert != null)
            {
                XmlSerializer serializer = new XmlSerializer(objectToConvert.GetType());
                using (StringWriter writer = new StringWriter(CultureInfo.InvariantCulture))
                {
                    serializer.Serialize((TextWriter)writer, objectToConvert);
                    str = writer.ToString();
                    writer.Close();
                }
            }
            return str;
        }
        /// <summary>
        /// 从二进制文件中序列化为对象。
        /// </summary>
        /// <typeparam name="T">要序列化的类型。</typeparam>
        /// <param name="path">绝对物理路径。</param>
        /// <returns>返回序列化后的对象。</returns>
        public static T LoadBinaryFile<T>(string path)
        {
            if (!File.Exists(path))
            {
                return default(T);
            }
            using (FileStream stream = new FileStream(path, FileMode.Open, FileAccess.Read))
            {
                BinaryReader reader = new BinaryReader(stream);
                byte[] buffer = new byte[stream.Length];
                reader.Read(buffer, 0, (int)stream.Length);
                return ConvertToObject<T>(buffer);
            }
        }
        /// <summary>
        /// 将对象二进制序列化后保存到文件中。
        /// </summary>
        /// <param name="objectToSave">当前对象。</param>
        /// <param name="path">保存绝对物理路径。</param>
        /// <returns>如果保存成功则返回<c>true</c>，否则返回<c>false</c>。</returns>
        public static bool SaveAsBinary(object objectToSave, string path)
        {
            if ((objectToSave != null) && CanBinarySerialize)
            {
                byte[] buffer = ConvertToBytes(objectToSave);
                if (buffer != null)
                {
                    using (FileStream stream = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write))
                    {
                        using (BinaryWriter writer = new BinaryWriter(stream))
                        {
                            writer.Write(buffer);
                            return true;
                        }
                    }
                }
            }
            return false;
        }
        /// <summary>
        /// 将对象序列化为XML并保存。
        /// </summary>
        /// <param name="objectToConvert">当前对象。</param>
        /// <param name="path">保存绝对物理路径。</param>
        public static void SaveAsXML(object objectToConvert, string path)
        {
            if (objectToConvert != null)
            {
                XmlSerializer serializer = new XmlSerializer(objectToConvert.GetType());
                using (StreamWriter writer = new StreamWriter(path))
                {
                    serializer.Serialize((TextWriter)writer, objectToConvert);
                    writer.Close();
                }
            }
        }
        /// <summary>
        /// 将键值对格式“k1=v1&amp;k2=v2...”格式化。
        /// </summary>
        /// <param name="str">当前字符串。</param>
        /// <returns>返回键值对集合对象。</returns>
        public static NameValueCollection FromString(string str)
        {
            if (string.IsNullOrEmpty(str))
                return null;
            str = str.Trim();
            NameValueCollection kvs = new NameValueCollection(StringComparer.OrdinalIgnoreCase);
            string key, value;
            int index = 0;
            foreach (string part in str.Split(new char[] { '&' }, StringSplitOptions.RemoveEmptyEntries))
            {
                index = part.IndexOf('=');
                if (index == -1)
                    continue;
                key = part.Substring(0, index);
                value = part.Substring(index + 1);
                if (kvs[key] != null)
                {
                    if (string.IsNullOrEmpty(value))
                        kvs.Remove(key);
                    else
                        kvs[key] = value;
                }
                else
                    kvs.Add(key, value);
            }
            return kvs;
        }
        /// <summary>
        /// 将对象序列化为字符串。
        /// </summary>
        /// <param name="objectToConvert">要序列化的对象。</param>
        /// <returns>返回序列化后的字符串。</returns>
        public static string ConvertToString(IDictionary<string, object> objectToConvert)
        {
            StringBuilder sb = new StringBuilder();
            object value = null;
            foreach (string key in objectToConvert.Keys)
            {
                value = objectToConvert[key];
                if (value == null || string.IsNullOrEmpty(value.ToString()))
                    continue;
                Type type = value.GetType();
                sb.AppendFormat("{0}:{1}:{2}:{3};", key, (int)Type.GetTypeCode(type), type.IsEnum ? ((int)value).ToString().Length : value.ToString().Length, type.IsEnum ? (int)value : value);
            }
            if (sb.Length == 0)
                return null;
            return sb.ToString();
        }
        /// <summary>
        /// 将字符串转换为字典实例对象。
        /// </summary>
        /// <param name="str">扩展字符串。</param>
        /// <param name="objects">字典对象实例。</param>
        /// <returns>返回字典对象实例。</returns>
        public static IDictionary<string, object> ConvertToObject(string str, IDictionary<string, object> objects)
        {
            if (objects == null)
                objects = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
            else
                objects.Clear();
            if (str != null)
            {
                int index = str.IndexOf(':');
                TypeCode typeCode;
                string value;
                int length;
                string key;
                while (index != -1)
                {
                    key = str.Substring(0, index);
                    str = str.Substring(index + 1);
                    index = str.IndexOf(':');
                    if (index == -1)
                        throw new Exception("Invalid Value String");
                    typeCode = (TypeCode)Convert.ToInt32(str.Substring(0, index));
                    str = str.Substring(index + 1);
                    index = str.IndexOf(':');
                    if (index == -1)
                        throw new Exception("Invalid Value String");
                    length = Convert.ToInt32(str.Substring(0, index));
                    str = str.Substring(index + 1);
                    value = str.Substring(0, length);
                    str = str.Substring(length + 1);
                    objects.Add(key, Convert.ChangeType(value, typeCode));
                    index = str.IndexOf(':');
                }
            }
            return objects;
        }
        #endregion

        #region contentlength
        /// <summary>
        /// 获取文件大小为TB的字节数。
        /// </summary>
        public static readonly long TBytes = 1024L * 1024 * 1024 * 1024;
        /// <summary>
        /// 获取文件大小为GB的字节数。
        /// </summary>
        public static readonly long GBytes = 1024L * 1024 * 1024;
        /// <summary>
        /// 获取文件大小为MB的字节数。
        /// </summary>
        public static readonly long MBytes = 1024L * 1024;
        /// <summary>
        /// 获取文件大小为KB的字节数。
        /// </summary>
        public static readonly long KBytes = 1024L;
        #endregion

        #region times
        /// <summary>
        /// 获取或设置年份时间。
        /// </summary>
        public const int YearSeconds = 365 * 60 * 60 * 24 * 30;
        /// <summary>
        /// 获取或设置月份时间。
        /// </summary>
        public const int MonthSeconds = 60 * 60 * 24 * 30;
        /// <summary>
        /// 获取或设置日期时间。
        /// </summary>
        public const int DaySeconds = 60 * 60 * 24;
        /// <summary>
        /// 获取或设置小时时间。
        /// </summary>
        public const int HourSeconds = 60 * 60;
        /// <summary>
        /// 获取或设置分钟时间。
        /// </summary>
        public const int MinuteSeconds = 60;
        #endregion

        #region type methods
        /// <summary>
        /// 创建当前字符串的类型实例对象。
        /// </summary>
        /// <typeparam name="T">返回当前实例对象类型。</typeparam>
        /// <param name="type">类型字符串。</param>
        /// <param name="args">初始化构造函数参数。</param>
        /// <returns>返回当前字符串的实例对象。</returns>
        public static T CreateInstance<T>(string type, params object[] args) where T:class {
            if (string.IsNullOrEmpty(type))
                throw new ArgumentNullException("type", "Type cannot be null!");
            Type oType = System.Type.GetType(type);
            if (oType == null)
                throw new Exception("The string of “" + type + "” can not get type!");
            T instance = Activator.CreateInstance(oType, args) as T;
            if (instance == null)
                throw new Exception("The type of “" + type + "” is not subclass of “" + typeof(T).FullName + "”!");
            return instance;
        }
        private static Dictionary<int, bool> isTypeCache = new Dictionary<int, bool>();
        /// <summary>
        /// 判断当前类型是否为需求类型或子类型。
        /// </summary>
        /// <param name="currentType">当前类型。</param>
        /// <param name="requestedType">需求类型。</param>
        /// <returns>如果符合就返回true。</returns>
        public static bool IsType(Type currentType, Type requestedType)
        {
            bool flag;
            int hashCode = currentType.GetHashCode();
            int key = (hashCode * requestedType.GetHashCode()) + hashCode;
            if (!isTypeCache.TryGetValue(key, out flag))
            {
                lock (isTypeCache)
                {
                    if (isTypeCache.TryGetValue(key, out flag))
                    {
                        return flag;
                    }
                    if (requestedType.IsInterface)
                    {
                        flag = currentType.GetInterface(requestedType.Name) != null;
                    }
                    else
                    {
                        flag = (currentType == requestedType) || currentType.IsSubclassOf(requestedType);
                    }
                    isTypeCache[key] = flag;
                }
            }
            return flag;
        }
        /// <summary>
        /// 判断两个类型是否为需求类型或子类型。
        /// </summary>
        /// <param name="currentType">当前类型。</param>
        /// <param name="requestedType">需求类型。</param>
        /// <returns>如果符合就返回true。</returns>
        public static bool MayBeType(Type currentType, Type requestedType)
        {
            if (!IsType(currentType, requestedType))
            {
                return IsType(requestedType, currentType);
            }
            return true;
        }
        /// <summary>
        /// 返回当前类型子类的对象集合。
        /// </summary>
        /// <param name="directoryName">查询DLL目录，默认(null)为bin</param>
        /// <param name="isAbstract">是否包含抽象类。</param>
        /// <returns>返回当前类型子类的对象集合。</returns>
        public static List<T> FindType<T>(string directoryName = null, bool isAbstract = false)
        {
            Type baseType = typeof(T);
            string baseDirectory = MapPath(directoryName ?? "~/bin");
            List<T> types = new List<T>();
            foreach (string file in Directory.GetFileSystemEntries(baseDirectory, "*.dll"))
            {
                try
                {
                    Assembly asm = Assembly.LoadFrom(file);
                    if (baseType.IsInterface)
                    {
                        foreach (Type t in asm.GetTypes())
                        {
                            if (!t.IsPublic || (!isAbstract && t.IsAbstract) || t.GetInterface(baseType.FullName) == null)
                                continue;
                            try
                            {
                                types.Add((T)asm.CreateInstance(t.FullName));
                            }
                            catch
                            {
                            }
                        }
                    }
                    else
                    {
                        foreach (Type t in asm.GetTypes())
                        {
                            if (!t.IsPublic || (!isAbstract && t.IsAbstract) || !t.IsSubclassOf(baseType))
                                continue;
                            try
                            {
                                types.Add((T)asm.CreateInstance(t.FullName));
                            }
                            catch
                            {
                            }
                        }
                    }
                }
                catch
                {
                }
            }
            return types;
        }
        /// <summary>
        /// 循环执行枚举中的所有值。
        /// </summary>
        /// <typeparam name="T">枚举类型，否则将抛出错误。</typeparam>
        /// <param name="action">执行枚举代理方法，参数为枚举当前值。</param>
        public static void ForEach<T>(Action<T> action) {
            Type type = typeof(T);
            if (type.IsEnum)
            {
                foreach (T value in Enum.GetValues(type))
                    action(value);
            }
        }
        #endregion

        #region encrypt or decrypt
        /// <summary>
        /// 加密字符串。
        /// </summary>
        /// <param name="encryptString">加密前的字符串。</param>
        /// <param name="encryptType">加密类型。</param>
        /// <returns>返回加密后的字符串。</returns>
        public static string Encrypt(string encryptString, Mozlite.Cryptography.EncryptionAlgorithm encryptType)
        {
            string salt = null;
            return Encrypt(encryptString, encryptType, ref salt);
        }
        /// <summary>
        /// 加密字符串。
        /// </summary>
        /// <param name="encryptString">加密前的字符串。</param>
        /// <param name="encryptType">加密类型。</param>
        /// <param name="salt">加密Salt，如果为空则返回此字符串。</param>
        /// <returns>返回加密后的字符串。</returns>
        public static string Encrypt(string encryptString, Mozlite.Cryptography.EncryptionAlgorithm encryptType, ref string salt)
        {
            if (encryptType == Mozlite.Cryptography.EncryptionAlgorithm.Clear)
                return encryptString;
            if (encryptType <= Mozlite.Cryptography.EncryptionAlgorithm.SHA512)
                return Cryptors.GetBase64(Cryptors.Make(encryptString, encryptType));
            Encryptor encrypt = new Encryptor(encryptType);
            if (!string.IsNullOrEmpty(salt))
            {
                string[] parts = salt.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
                encrypt.IV = Convert.FromBase64String(parts[1]);
                encryptString = Cryptors.GetBase64(encrypt.Encrypt(Encoding.Unicode.GetBytes(encryptString), Convert.FromBase64String(parts[0])));
            }
            else
            {
                encryptString = Cryptors.GetBase64(encrypt.Encrypt(Encoding.Unicode.GetBytes(encryptString), null));
                salt = Cryptors.GetBase64(encrypt.Key) + "|" + Cryptors.GetBase64(encrypt.IV);
            }
            return encryptString;
        }
        /// <summary>
        /// 对对称加密的字符串进行解密。
        /// </summary>
        /// <param name="decryptString">加密后的Base64字符串。</param>
        /// <param name="encryptType">加密类型。</param>
        /// <param name="salt">加密Salt。</param>
        /// <returns>返回解密后的字符串。</returns>
        public static string Decrypt(string decryptString, Mozlite.Cryptography.EncryptionAlgorithm encryptType, string salt)
        {
            if (encryptType <= Mozlite.Cryptography.EncryptionAlgorithm.SHA512)
                return decryptString;
            Decryptor decrypt = new Decryptor(encryptType);
            string[] parts = salt.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
            decrypt.IV = Convert.FromBase64String(parts[1]);
            decryptString = Encoding.Unicode.GetString(decrypt.Decrypt(Convert.FromBase64String(decryptString), Convert.FromBase64String(parts[0])));
            return decryptString;
        }
        #endregion

        #region download files
        /// <summary>
        /// 下载文件。
        /// </summary>
        /// <param name="response">HTTP输出实例对象。</param>
        /// <param name="request">HTTP请求实例对象。</param>
        /// <param name="filePath">要写入 HTTP 输出的文件名。</param>
        /// <param name="outputFileName">输出文件名称的扩展名。</param>
        /// <returns>如果输出成功返回<c>true</c>，否则返回<c>false</c>。</returns>
        public static bool DownloadFile(HttpResponse response, HttpRequest request, string filePath, string outputFileName)
        {
            return DownloadFile(response, request, filePath, outputFileName, true, false);
        }
        /// <summary>
        /// 下载文件。
        /// </summary>
        /// <param name="response">HTTP输出实例对象。</param>
        /// <param name="request">HTTP请求实例对象。</param>
        /// <param name="filePath">要写入 HTTP 输出的文件名。</param>
        /// <param name="outputFileName">输出文件名称的扩展名。</param>
        /// <param name="responseEnd">是否结束此次输出。</param>
        /// <returns>如果输出成功返回<c>true</c>，否则返回<c>false</c>。</returns>
        public static bool DownloadFile(HttpResponse response, HttpRequest request, string filePath, string outputFileName, bool responseEnd)
        {
            return DownloadFile(response, request, filePath, outputFileName, responseEnd, false);
        }
        /// <summary>
        /// 下载文件。
        /// </summary>
        /// <param name="response">HTTP输出实例对象。</param>
        /// <param name="request">HTTP请求实例对象。</param>
        /// <param name="filePath">要写入 HTTP 输出的文件名。</param>
        /// <param name="outputFileName">输出文件名称的扩展名。</param>
        /// <param name="responseEnd">是否结束此次输出。</param>
        /// <param name="clearCache">是否清楚缓存。</param>
        /// <returns>如果输出成功返回<c>true</c>，否则返回<c>false</c>。</returns>
        public static bool DownloadFile(HttpResponse response, HttpRequest request, string filePath, string outputFileName, bool responseEnd, bool clearCache)
        {
            try
            {
                response.ClearContent();
                if (!string.IsNullOrEmpty(outputFileName))
                {
                    response.ContentType = MimeTypes.GetContentType(outputFileName);
                    response.AddHeader("Content-Disposition", "attachment; filename=" + HttpUtility.UrlEncode(Encoding.UTF8.GetBytes(outputFileName)));
                }
                response.TransmitFile(filePath);
                if (clearCache)
                {
                    response.Cache.SetCacheability(HttpCacheability.NoCache);
                    response.Cache.SetNoStore();
                }
                if (responseEnd)
                {
                    response.End();
                }
            }
            catch
            {
                return false;
            }
            return true;
        }
        #endregion

        #region images
        /// <summary>
        /// 获取图片的格式。
        /// </summary>
        /// <param name="image">图片实例对象。</param>
        /// <param name="extension">返回扩展名称（不带.）。</param>
        /// <returns>返回图片格式。</returns>
        public static ImageFormat GetFormat(Bitmap image, out string extension)
        {
            ImageFormat format;
            if (image.RawFormat.Guid == ImageFormat.Png.Guid || image.RawFormat.Guid == ImageFormat.Gif.Guid)
                format = ImageFormat.Png;
            else
                format = ImageFormat.Jpeg;
            extension = format.ToString().ToLower();
            if (extension == "jpeg")
            {
                extension = "jpg";
            }
            return format;
        }
        /// <summary>
        /// 将图片转换后保存。
        /// </summary>
        /// <param name="path">当前图片地址。</param>
        /// <param name="width">图片的长度。</param>
        /// <param name="height">图片的高度。</param>
        /// <param name="executeFileNameForParamExtension">获取保存后的文件名，参数为当前文件的扩展名，不包含“.”。</param>
        /// <param name="realSize">是否使用真实大小，即<paramref name="width"/>和<paramref name="height"/>指定的大小。</param>
        public static void SaveImage(string path, int width, int height, Func<string, string> executeFileNameForParamExtension, bool realSize = false)
        {
            if (!File.Exists(path))
                throw new Exception(string.Format("File “{0}” is not existed!", path));
            SaveImage(System.Drawing.Image.FromFile(path), width, height, executeFileNameForParamExtension, realSize);
        }
        /// <summary>
        /// 将图片转换后保存。
        /// </summary>
        /// <param name="img">当前图片实例对象。</param>
        /// <param name="width">图片的长度。</param>
        /// <param name="height">图片的高度。</param>
        /// <param name="executeFileNameForParamExtension">获取保存后的文件名，参数为当前文件的扩展名，不包含“.”。</param>
        /// <param name="realSize">是否使用真实大小，即<paramref name="width"/>和<paramref name="height"/>指定的大小。</param>
        public static void SaveImage(System.Drawing.Image img, int width, int height, Func<string, string> executeFileNameForParamExtension, bool realSize = false)
        {
            Bitmap image = new Bitmap(img);
            string extension;
            ImageFormat format = GetFormat(image, out extension);

            string path = executeFileNameForParamExtension(extension);
            CreateDirectory(Path.GetDirectoryName(path));
            Bitmap bitmap = image;
            if (image.Height > height || image.Width > width)
            {
                float rate = Math.Min((float)(((float)height) / ((float)image.Height)), (float)(((float)width) / ((float)image.Width)));
                int realWidth = realSize ? width : (int)(rate * image.Width);
                int realHeight = realSize ? height : (int)(rate * image.Height);
                bitmap = new Bitmap(realWidth, realHeight);
                using (Graphics graphics = Graphics.FromImage(bitmap))
                {
                    graphics.Clear(Color.Transparent);
                    graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
                    graphics.DrawImage(image, 0, 0, realWidth, realHeight);
                }
            }

            ImageCodecInfo encoder = null;
            foreach (ImageCodecInfo info in ImageCodecInfo.GetImageEncoders())
            {
                if (info.FormatID == format.Guid)
                {
                    encoder = info;
                    break;
                }
            }

            if (format.Guid == ImageFormat.Gif.Guid)
            {
                foreach (Color color in bitmap.Palette.Entries)
                {
                    if (color.A == 0)
                    {
                        bitmap.MakeTransparent(color);
                    }
                }
            }

            EncoderParameters encoderParams = new EncoderParameters(1);
            encoderParams.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 0x55L);
            bitmap.Save(path, encoder, encoderParams);
            if (bitmap != image)
            {
                bitmap.Dispose();
            }
            image.Dispose();
        }
        /// <summary>
        /// 获取图片的HTML字符串，IMG标签。
        /// </summary>
        /// <param name="image">图片控件实例对象。</param>
        /// <param name="width">宽。</param>
        /// <param name="height">高。</param>
        public static void ResizeImage(System.Web.UI.WebControls.Image image, int width, int height)
        {
            HttpContext current = HttpContext.Current;
            if ((current == null) || (current.Request.Browser.IsBrowser("IE") && (current.Request.Browser.MajorVersion < 7)))
            {
                if (height > 0)
                {
                    image.Height = new Unit(height);
                }
                if (width > 0)
                {
                    image.Width = new Unit(width);
                }
            }
            else
            {
                if (height > 0)
                {
                    image.Style["max-height"] = height.ToString() + "px";
                }
                if (width > 0)
                {
                    image.Style["max-width"] = width.ToString() + "px";
                }
            }
        }
        /// <summary>
        /// 获取图片的HTML字符串，IMG标签。
        /// </summary>
        /// <param name="url">图片地址。</param>
        /// <param name="width">宽。</param>
        /// <param name="height">高。</param>
        /// <param name="alt">提示字符串。</param>
        /// <param name="useHtmlResizing">是否使用HTML重置大小。</param>
        /// <param name="addAbsMiddle">是否加入absmiddle对其模式。</param>
        /// <returns>返回IMG标签的HTML字符串。</returns>
        public static string ResizeImage(string url, int width, int height, string alt, bool useHtmlResizing = true, bool addAbsMiddle = false)
        {
            StringBuilder builder = new StringBuilder();
            builder.Append("<img src=\"");
            builder.Append(HttpUtility.HtmlEncode(url));
            builder.AppendFormat("\" alt=\"{0}\"", alt);
            if (useHtmlResizing && ((width > 0) || (height > 0)))
            {
                HttpContext current = HttpContext.Current;
                if ((current == null) || (current.Request.Browser.IsBrowser("IE") && (current.Request.Browser.MajorVersion < 7)))
                {
                    if (height > 0)
                    {
                        builder.Append(" height=\"");
                        builder.Append(height.ToString());
                        builder.Append("\"");
                    }
                    if (width > 0)
                    {
                        builder.Append(" width=\"");
                        builder.Append(width.ToString());
                        builder.Append("\"");
                    }
                }
                else
                {
                    builder.Append(" style=\"");
                    if (height > 0)
                    {
                        builder.Append("max-height: ");
                        builder.Append(height.ToString());
                        builder.Append("px;");
                    }
                    if (width > 0)
                    {
                        builder.Append("max-width: ");
                        builder.Append(width.ToString());
                        builder.Append("px;");
                    }
                    builder.Append("\"");
                }
            }
            if (addAbsMiddle)
                builder.Append(" align=\"absmiddle\"");
            builder.Append(" />");
            return builder.ToString();
        }
        /// <summary>
        /// 下载远程文件。
        /// </summary>
        /// <param name="path">提供文件路径的文件物理路径。</param>
        /// <param name="pattern">获取需要下载的文件路径的正在表达式。</param>
        /// <param name="directory">保存下载后路径的文件夹。</param>
        /// <param name="imagePathHeader">正则表达式获取后需要增加前缀来获得远程文件路径。</param>
        public static void DownLoadFromFile(string path, string pattern, string directory, string imagePathHeader = null)
        {
            CreateDirectory(directory);
            Dictionary<string, string> files = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
            try
            {
                string file = File.ReadAllText(path);
                if (string.IsNullOrEmpty(file))
                    return;
                Regex regex = new Regex(pattern, RegexOptions.Compiled | RegexOptions.IgnoreCase);
                foreach (Match match in regex.Matches(file))
                {
                    string imageUrl = match.Groups[1].Value.Trim();
                    string savePath = Combine(directory, Path.GetFileName(imageUrl));
                    if (!string.IsNullOrEmpty(imagePathHeader))
                        imageUrl = Combine(imagePathHeader, imageUrl);
                    if (files.ContainsKey(imageUrl))
                        files.Add(imageUrl, savePath);
                }
            }
            catch { }
            if (files.Count > 0)
            {
                WebClient client = new WebClient();
                client.Headers.Add("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2;)");
                foreach (KeyValuePair<string, string> file in files)
                {
                    client.DownloadFile(file.Key, file.Value);
                }
            }
        }
        /// <summary>
        /// 下载远程文件。
        /// </summary>
        /// <param name="url">URL地址。</param>
        /// <param name="directory">保存的目录。</param>
        /// <returns>返回当前文件保存的物理路径。</returns>
        public static string DownLoadRemoteFile(string url, string directory)
        {
            CreateDirectory(directory);
            directory = Combine(directory, GetFileName(url), true);
            WebClient client = new WebClient();
            client.Headers.Add("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2;)");
            client.DownloadFile(url, directory);
            return directory;
        }
        /// <summary>
        /// 获取文件名称。
        /// </summary>
        /// <param name="path">路径，可以是URL地址。</param>
        /// <returns>返回文件名称。</returns>
        public static string GetFileName(string path)
        {
            try
            {
                Uri uri = new Uri(path);
                return Path.GetFileName(uri.AbsolutePath);
            }
            catch
            {
                return Path.GetFileName(path);
            }
        }
        /// <summary>
        /// 改变图片大小。
        /// </summary>
        /// <param name="stream">文件流。</param>
        /// <param name="height">高。</param>
        /// <param name="width">宽度。</param>
        /// <param name="format">格式。</param>
        /// <returns>返回内存流。</returns>
        public static MemoryStream ResizeImage(Stream stream, int height, int width, ImageFormat format)
        {
            Bitmap image = new Bitmap(stream);
            Bitmap bitmap = image;
            if ((image.Height > height) || (image.Width > width))
            {
                float grouth = Math.Min((float)(((float)height) / ((float)image.Height)), (float)(((float)width) / ((float)image.Width)));
                int gwidth = (int)(grouth * image.Width);
                int gheight = (int)(grouth * image.Height);
                bitmap = new Bitmap(gwidth, gheight);
                using (Graphics graphics = Graphics.FromImage(bitmap))
                {
                    graphics.Clear(Color.Transparent);
                    graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
                    graphics.DrawImage(image, 0, 0, gwidth, gheight);
                }
            }
            ImageCodecInfo encoder = null;
            foreach (ImageCodecInfo info in ImageCodecInfo.GetImageEncoders())
            {
                if (info.FormatID == format.Guid)
                {
                    encoder = info;
                    break;
                }
            }
            EncoderParameters encoderParams = new EncoderParameters(1);
            encoderParams.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 0x4bL);
            MemoryStream ms = new MemoryStream();
            bitmap.Save(ms, encoder, encoderParams);
            if (bitmap != image)
            {
                bitmap.Dispose();
            }
            image.Dispose();
            return ms;
        }
        #endregion

        #region memory
        /// <summary>
        /// 获取当前程序使用物理内存实例对象。
        /// </summary>
        /// <returns>返回内存实例对象。</returns>
        public static MemoryInfo GetGlobalMemory()
        {
            MemoryInfo memoryInfo = new MemoryInfo();
            GlobalMemoryStatus(ref memoryInfo);
            return memoryInfo;
        }
        /// <summary>
        /// 获取当前应用程序内存使用量。
        /// </summary>
        /// <returns>返回当前应用程序内存使用量。</returns>
        public static long GetCurrentMemory() { 
            return Process.GetCurrentProcess().NonpagedSystemMemorySize64;
        }

        [DllImport("kernel32")]
        static extern void GlobalMemoryStatus(ref MemoryInfo memoryInfo);
        #endregion

        #region Environment
        /// <summary>
        /// 获取当前系统信息。
        /// </summary>
        public static OperatingSystem OSVersion {
            get {
                return Environment.OSVersion;
            }
        }
        /// <summary>
        /// 获取机器名称。
        /// </summary>
        public static string MachineName
        {
            get {
                return Environment.MachineName;
            }
        }
        /// <summary>
        /// .NET版本信息。
        /// </summary>
        public static Version DotNetVersion {
            get {
                return Environment.Version;
            }
        }
        /// <summary>
        /// 获取当前工作物理路径。
        /// </summary>
        public static string WorkDirectory {
            get {
                return HostingEnvironment.ApplicationPhysicalPath;
            }
        }
        /// <summary>
        /// 重启应用程序。
        /// </summary>
        public static void ResetApplication() {
            HostingEnvironment.InitiateShutdown();
        }
        /// <summary>
        /// 获取当前类型的版本。
        /// </summary>
        /// <param name="type">类型。</param>
        /// <returns>返回当前类型版本。</returns>
        public static Version GetVersion(Type type) {
           return type.Assembly.GetName().Version;
        }
        #endregion
    }
}
